package com.csun.cmny.provider.task;

import com.alibaba.fastjson.JSON;
import com.csun.cmny.base.constant.JiGuangConstant;
import com.csun.cmny.provider.device.csun.camera.CameraMessageHandler;
import com.csun.cmny.provider.device.csun.gateway.GatewayMessageSender;
import com.csun.cmny.provider.device.csun.sleep.SleepMessageHandler;
import com.csun.cmny.provider.device.csun.sleep.SleepMessageSender;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.constant.LifeConstant;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.SendMessageRequest;
import com.csun.cmny.provider.model.dto.patrol.PatrolRecordQueryDto;
import com.csun.cmny.provider.model.vo.LifeRoomBuildingVo;
import com.csun.cmny.provider.model.vo.OldmanBedRoomBuildingVo;
import com.csun.cmny.provider.model.vo.csunversion.VersionSetVo;
import com.csun.cmny.provider.model.vo.patrol.PatrolGreatConfigVo;
import com.csun.cmny.provider.model.vo.patrol.PatrolGreatVo;
import com.csun.cmny.provider.model.vo.patrol.PatrolPointVo;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.DateUtil;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class RefreshExpireKeyQuartz extends QuartzJobBean {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private DmcLifeTransducerRoomConfigService dmcLifeTransducerRoomConfigService;
    @Resource
    private DmcLifeTransducerDefaultConfigService dmcLifeTransducerDefaultConfigService;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;
    @Resource
    private DmcCsunVersionSetService dmcCsunVersionSetService;
    @Resource
    private DmcCsunVersionSetDeviceService dmcCsunVersionSetDeviceService;
    @Resource
    private CameraMessageHandler cameraMessageHandler;
    @Resource
    private GatewayMessageSender gatewayMessageSender;
    @Resource
    private SleepMessageSender sleepMessageSender;
    @Resource
    private DmcGuoKangClientService dmcGuoKangClientService;
    @Autowired
    private RestTemplate myRestTemplate;
    @Resource
    private DmcPatrolReminderService dmcPatrolReminderService;
    @Resource
    private DmcPatrolPointBindService dmcPatrolPointBindService;
    @Resource
    private DmcPatrolGreatConfigService dmcPatrolGreatConfigService;
    @Resource
    private DmcPatrolRecordService dmcPatrolRecordService;
    @Resource
    private OpcMessageService opcMessageService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        String str = DateUtil.YYYY_MM_DD_MM_HH_SS.format(new Date());

        log.debug("=====> chisj refresh quartz = {}", str);

        refresh();

        deviceUpdateCheck(str);

        // checkOldmanInRoomAtNight(str.substring(11, 19));

        uploadSleepMonthReport(str);

        patrolReminderCheck(str);
    }

    /**
     * 校验巡更记录，生成巡更提醒
     *
     * @param date
     */
    private void patrolReminderCheck(String date) {

        if (!date.endsWith("00")) {
            return ;
        }
        // 获取小时:分钟
        String str_date = date.substring(0, 10);
        String time = date.substring(11, 16);
        log.info("patrol reminder check date = {}, time = {}", str_date, time);

        patrolReminderUpdate(date);

        // 查询已绑定巡更棒及配置
        List<PatrolGreatVo> patrolGreatVoList = dmcPatrolPointBindService.queryPatrolGreatList();
        for (PatrolGreatVo pgv : patrolGreatVoList) {
            List<PatrolGreatConfigVo> patrolGreatConfigVoList = dmcPatrolGreatConfigService
                    .queryConfigByGreatId(pgv.getGreatId(), pgv.getGroupId());
            for (PatrolGreatConfigVo pgcv : patrolGreatConfigVoList) {
                if (pgcv.getPatrolTime().equals(time)) {
                    for (PatrolPointVo ppv : pgv.getPatrolPointVoList()) {
                        PatrolRecordQueryDto patrolRecordQueryDto = new PatrolRecordQueryDto();
                        patrolRecordQueryDto.setGreatId(pgv.getGreatId());
                        patrolRecordQueryDto.setPointId(ppv.getPointId());
                        patrolRecordQueryDto.setStartTime(str_date + " " + pgcv.getPatrolStart() + ":00");
                        patrolRecordQueryDto.setEndTime(str_date + " " + pgcv.getPatrolEnd() + ":00");
                        // 查询巡更棒指定时间内是否有巡更记录
                        int count = dmcPatrolRecordService.queryCount(patrolRecordQueryDto);
                        if (count < 1) {
                            // 产生提醒 并 推送
                            DmcPatrolReminder dmcPatrolReminder = new DmcPatrolReminder();
                            dmcPatrolReminder.setUserId(pgv.getUserId());
                            dmcPatrolReminder.setUserName(pgv.getUserName());
                            dmcPatrolReminder.setGreatId(pgv.getGreatId());
                            dmcPatrolReminder.setGreatNo(pgv.getGreatNo());
                            dmcPatrolReminder.setGroupId(pgv.getGroupId());
                            dmcPatrolReminder.setLocation(ppv.getLocation());
                            dmcPatrolReminder.setPointId(ppv.getPointId());
                            dmcPatrolReminder.setPointNo(ppv.getPointNo());
                            dmcPatrolReminder.setPatrolDuration(pgcv.getPatrolDuration());
                            dmcPatrolReminder.setPatrolTime(str_date + " " + pgcv.getPatrolTime() + ":00");
                            dmcPatrolReminder.setPatrolStart(str_date + " " + pgcv.getPatrolStart() + ":00");
                            dmcPatrolReminder.setPatrolEnd(str_date + " " + pgcv.getPatrolEnd() + ":00");
                            // 生成巡更提醒记录
                            dmcPatrolReminderService.save(dmcPatrolReminder);

                            // 通知用户前往巡更
                            SendMessageRequest sendMessageRequest = new SendMessageRequest();
                            sendMessageRequest.setMsgCode("patrol_reminder_create");
                            sendMessageRequest.setUserIdList(Lists.newArrayList(pgv.getUserId()));
                            sendMessageRequest.setTagList(Lists.newArrayList(JiGuangConstant.TAG_PREFIX_USER
                                    + pgv.getUserId()));
                            sendMessageRequest.setExtrasParam(dmcPatrolReminder);
                            sendMessageRequest.setMessage(JSON.toJSONString(dmcPatrolReminder));
                            sendMessageRequest.setGroupId(pgv.getGroupId());
                            opcMessageService.pushWithMsgCode(sendMessageRequest);
                        }
                    }
                }
            }
        }
    }

    /**
     * 更新巡更提醒状态
     *
     * @param date
     */
    private void patrolReminderUpdate(String date) {

        // 查询巡更提醒记录（待巡更）
        List<DmcPatrolReminder> patrolReminderList = dmcPatrolReminderService.queryWaitList(date);

        // 更新巡更提醒（已超时）
        for (DmcPatrolReminder pr : patrolReminderList) {
            pr.setStatus(3);
            pr.setUpdateTime(new Date());
            dmcPatrolReminderService.update(pr);
        }
    }

    /**
     * 上传床垫月度报表
     *
     * @param date
     */
    private void uploadSleepMonthReport(String date) {

        String time = "11 13:37:30";    // 上传时间
        String timeRedis = (String) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunSleepReportTime());
        if (PublicUtil.isNotEmpty(timeRedis)) {
            time = timeRedis;
        }

        String month = date.substring(0, 7);

        if (date.endsWith(time)) {

            // 获取上个月日期
            month = DateUtil.getLastMonth(month);

            log.info("=====> chisj upload sleep month report...");
            dmcGuoKangClientService.uploadSleepMonthReport(month);
        }
    }

    public void deviceUpdateCheck(String time) {

        // 管理员处理超时
        dmcCsunVersionSetDeviceService.updateByTimeAndStat(time,
                DeviceConstant.VERSION_SET_SH_YES, DeviceConstant.VERSION_SET_BOSS_DELAY);

        // 查询boss审批通过的配置及设备集合
        List<VersionSetVo> versionSetVoList = dmcCsunVersionSetService.queryVersionSetVoList(time);
        for (VersionSetVo set : versionSetVoList) {

            // 查询设备Id
            List<DmcDevice> dmcDeviceList = dmcCsunVersionSetDeviceService.queryDeviceIdList(set.getId(),
                    DeviceConstant.VERSION_SET_BOSS_YES);
            // 判断是否有需要升级的设备
            if (PublicUtil.isEmpty(dmcDeviceList)) {
                continue;
            }
            // 根据版本类型 下发不同的升级指令
            switch (set.getFileType()) {
                case DeviceConstant.CSUN_CAMERA :
                    cameraMessageHandler.sendUpdateVersionMsg(dmcDeviceList, set);
                    break;
                case DeviceConstant.CSUN_GATEWAY :
                    gatewayMessageSender.sendUpdateVerMsg(dmcDeviceList, set);
                    break;
                case DeviceConstant.CSUN_SLEEP :
                    sleepMessageSender.sendUpdateVerMsg(dmcDeviceList, set);
                    break;
                default:
                    log.warn("未定义升级指令下发流程.");
                    break;
            }
        }
    }

    public void refresh() {

        /*
         * 触发失效key
         * */
        if (!SleepMessageHandler.expireRedisKeySet.isEmpty()) {
            for (String key : SleepMessageHandler.expireRedisKeySet) {
                redisTemplate.hasKey(key);
            }
        }
    }

    /**
     *
     * @param currentTime  格式 mm:hh:ss
     */
    public void checkOldmanInRoomAtNight(String currentTime) {

        log.info("=========================> nightAlertTime = [{}]",currentTime);

        //查询机构默认配置
        List<DmcLifeTransducerDefaultConfig> dmcLifeTransducerDefaultConfigs = dmcLifeTransducerDefaultConfigService.selectAll();
        for (DmcLifeTransducerDefaultConfig defaultConfig : dmcLifeTransducerDefaultConfigs) {

            String defaultLeaveRoomAlertStartTime = defaultConfig.getLeaveRoomAlertStartTime();
            String defaultLeaveRoomAlertEndTime = defaultConfig.getLeaveRoomAlertEndTime();
            Long groupId = defaultConfig.getGroupId();

            //定义map key-roomId value-defaultLeaveRoomAlertStartTime
            Map<Long, String> roomTimeMap = new HashMap<>();

            //如果开启了报警 查询出该机构所有的房间
            if (!PublicUtil.isEmpty(defaultLeaveRoomAlertStartTime) && !PublicUtil.isEmpty(defaultLeaveRoomAlertStartTime)) {
                if (!(defaultLeaveRoomAlertStartTime.equals(LifeConstant.DEFAULT_LEAVE_ROOM_ALERT_START_TIME) &&
                        defaultLeaveRoomAlertEndTime.equals(LifeConstant.DEFAULT_LEAVE_ROOM_ALERT_END_TIME))) {

                    //如果当前时间为默认报警开始时间
                    if (currentTime.equals(defaultLeaveRoomAlertStartTime)) {
                        //查询机构所有房间 放入map
                        List<LifeRoomBuildingVo> lifeRoomBuildingVos = omcRpcService.listRoomByGroupId(groupId);
                        lifeRoomBuildingVos.forEach(v -> roomTimeMap.put(v.getRoomId().longValue(), defaultLeaveRoomAlertStartTime));
                    }
                }
            }

            //查询机构所有房间配置
            DmcLifeTransducerRoomConfig configQuery = new DmcLifeTransducerRoomConfig();
            configQuery.setGroupId(groupId);
            List<DmcLifeTransducerRoomConfig> dmcLifeTransducerRoomConfigs = dmcLifeTransducerRoomConfigService.select(configQuery);
            for (DmcLifeTransducerRoomConfig config : dmcLifeTransducerRoomConfigs) {

                String leaveRoomAlertStartTime = config.getLeaveRoomAlertStartTime();
                String leaveRoomAlertEndTime = config.getLeaveRoomAlertEndTime();
                Long roomId = config.getRoomId();

                if (!PublicUtil.isEmpty(leaveRoomAlertStartTime) && !PublicUtil.isEmpty(leaveRoomAlertEndTime)) {
                    //如果开启了报警 放入map 更新map中的开始报警时间value
                    if (!(leaveRoomAlertStartTime.equals(LifeConstant.DEFAULT_LEAVE_ROOM_ALERT_START_TIME) &&
                            leaveRoomAlertEndTime.equals(LifeConstant.DEFAULT_LEAVE_ROOM_ALERT_END_TIME))) {
                        roomTimeMap.put(roomId, leaveRoomAlertStartTime);
                    }
                }
            }

            //通过设备信息判别是否推送报警
            roomTimeMap.forEach((k, v) -> {
//                log.info("====================> roomId = [{}] startTime = [{}]",k,v);
                if (v.equals(currentTime)) {
//                    log.info("===================> AlertRoom roomId = [{}]",k);
                    DmcDeviceAlert dmcDeviceAlert = new DmcDeviceAlert();
                    OldmanBedRoomBuildingVo obrvo = new OldmanBedRoomBuildingVo();
                    int i = dmcDeviceAlertService.checkOldmanInRoomAndAlert(k.intValue(), groupId, dmcDeviceAlert, obrvo);
                    if(i > 0){
                        dmcDeviceAlertService.sendDeviceAlertMsg(dmcDeviceAlert,obrvo);
                        dmcDeviceAlertService.sendLifeMsg(dmcDeviceAlert, obrvo, LifeConstant.YES_SOUND);
                    }
                }
            });
        }
    }
}
